﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using SX.Core;
using SX.Core.Attributes;
using SX.ProductService.Repository.Core;
using SX.ProductService.Service;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;

namespace SX.ProductService.API
{
    /// <summary>
    /// 初始化权限数据
    /// </summary>
    public class ApplicationHelper:DbContext
    {
        private static List<PermissionAddModel> list = new List<PermissionAddModel>();

        public  ApplicationHelper()
        {
            RedisHelper.Initialization(new CSRedis.CSRedisClient(ConfigHelper.Get("RedisConnStr")));
        }
        /// <summary>
        /// 初始化菜单和权限
        /// </summary>
        /// <param name="_parse_type"></param>
        public async Task Init(List<Type> types)
        {
            try
            {
                int menuIndex = 0;
                int apiIndex = 0;
                //遍历所有类
                foreach (var type in types)
                {
                    string className = type.Name.ToLower();
                    if (!className.EndsWith("controller") || (className == "basecontroller")) continue;

                    //控制器名称
                    string strcontroller = type.Name.ToLower();
                    strcontroller = strcontroller.Replace("controller", "");
                    //控制器的Area
                    object[] attributesArea = type.GetCustomAttributes(typeof(AreaAttribute), true);
                    var areaStr = "";
                    if (attributesArea != null && attributesArea.Length == 1)
                    {
                        AreaAttribute area = attributesArea[0] as AreaAttribute;
                        areaStr = area.RouteValue.ToLower();
                    }
                    //描述信息
                    object[] desAttrbutes = type.GetCustomAttributes(typeof(DescriptionAttribute), true);
                    var desStr = "";
                    if (desAttrbutes != null && desAttrbutes.Length == 1)
                    {
                        DescriptionAttribute desc = desAttrbutes[0] as DescriptionAttribute;
                        desStr = desc.Description.ToLower();
                    }

                    //遍历所有方法
                    MethodInfo[] methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly);
                    //如果控制器下无方法
                    if (methods == null || methods.Count() <= 0) continue;

                    //如果有MenuAttribute 需要自动生成菜单
                    var menuId = string.Empty;
                    object[] menuAttrbutes = type.GetCustomAttributes(typeof(MenuAttribute), true);
                    if (menuAttrbutes != null && menuAttrbutes.Length == 1)
                    {
                        menuId = GuidHelper.NewSequentialGuid();
                        //菜单
                        list.Add(new PermissionAddModel
                        {
                            Id = menuId,
                            Name = desStr,
                            Code = $"{areaStr}_{strcontroller}",
                            Path = $"/{areaStr}/{strcontroller}",
                            Icon = "menu-module",//默认菜单Icon
                            Sort = menuIndex,
                            Type = 0,//menu
                            CreateTime = DateTime.Now,
                            Enabled = 1,
                            Remarks = "自动生成",
                            ParentId = "0"//设为0 表示是默认根节点
                        });
                        menuIndex++;
                    }
                    //Aciton
                    foreach (var method in methods)//遍历方法
                    {
                        object[] allAttrbutes_Method = method.GetCustomAttributes(typeof(AllowAnonymousAttribute), true);
                        object[] commonAttrbutes_Method = method.GetCustomAttributes(typeof(CommonAttribute), true);
                        //如果是公开接口则不写入数据库
                        if ((allAttrbutes_Method != null && allAttrbutes_Method.Length > 0) || (commonAttrbutes_Method != null && commonAttrbutes_Method.Length > 0))
                        {
                            continue;
                        }
                        var desStr_Method = string.Empty;
                        object[] desAttrbutes_Method = method.GetCustomAttributes(typeof(DescriptionAttribute), true);
                        if (desAttrbutes != null && desAttrbutes.Length == 1)
                        {
                            DescriptionAttribute des = desAttrbutes_Method[0] as DescriptionAttribute;
                            desStr_Method = des.Description.ToLower();
                        }
                        list.Add(new PermissionAddModel
                        {
                            Id = GuidHelper.NewSequentialGuid(),
                            Name = desStr_Method,
                            Code = $"{areaStr}_{strcontroller}_{method.Name.ToLower()}",
                            Path = "",
                            Icon = "",//默认菜单Icon
                            Sort = apiIndex,
                            Type = 1,//action
                            CreateTime = DateTime.Now,
                            Enabled = 1,
                            Remarks = "自动生成",
                            ParentId =menuId
                        });
                        apiIndex++;
                    }
                }
                //存入redis 
                //RedisHelper.Del("Permission:Init");
                //RedisHelper.LPush("Permission:Init", list);             
                //var aaa=  RedisHelper.LRange("Permission:Init", 0, -1).ToList();
                var listtoAdd = new List<PermissionAddModel>();
                if (list.Count > 0)
                {
                    var oldJson = RedisHelper.Get("Permission:Init");
                    if (oldJson != null)
                    {
                        var listOld = JsonHelper.DeserializeObject<List<PermissionAddModel>>(oldJson);
                        if (listOld.Count > 0)
                        {
                            foreach (var item in list)
                            {
                                if (!listOld.Any(x => x.Code == item.Code))
                                {
                                    listtoAdd.Add(item);
                                }
                                var update=  listOld.Where(x => x.Code == item.Code && x.Name != item.Name).FirstOrDefault();
                                if(update!=null)
                                update.Name = item.Name;
                            }
                            if (listtoAdd.Count > 0)
                            {
                                listOld.AddRange(listtoAdd);                              
                            }
                            RedisHelper.Set("Permission:Init", JsonHelper.SerializeObject(listOld));
                        }
                    }
                    else
                    {
                        RedisHelper.Set("Permission:Init", JsonHelper.SerializeObject(list));
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"初始化权限数据失败：{ex.Message}");
            }
        }
    }
}
